package cn.hznc.configuration;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hznc.controller.service.inventory.InventoryLocationService;
import cn.hznc.controller.service.message.MessageService;
import cn.hznc.controller.service.schedule.ToolScheduleService;
import cn.hznc.domain.entity.*;
import cn.hznc.domain.request.inventory.InboundAssemblyReq;
import cn.hznc.domain.request.inventory.OutboundUniqueAssemblyReq;
import cn.hznc.domain.request.inventory.UniqueAssemblyToolVo;
import cn.hznc.exception.ToolLifeCycleException;
import cn.hznc.mapper.*;
import cn.hznc.repository.*;
import cn.hznc.utils.CommonUtil;
import cn.hznc.vo.AddTimeDataLogVo;
import cn.hznc.vo.IncBoxParamVo;
import cn.hznc.vo.WarehouseSnVo;
import cn.nerc.nclink.core.communication.DeviceClient;
import cn.nerc.nclink.core.exception.InvalidIdException;
import cn.nerc.nclink.core.exception.InvalidItemException;
import cn.nerc.nclink.core.exception.InvalidMessageException;
import cn.nerc.nclink.core.exception.InvalidRequestException;
import cn.nerc.nclink.core.general.InvalidException;
import cn.nerc.nclink.core.general.Operation;
import cn.nerc.nclink.core.message.QueryRequestItem;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @Author：Administrator
 * @Date：2023/6/9 10:34
 */
@Component
@Slf4j
public class SystemInit {

    @Resource
    private ToolPartRespository toolPartRespository;

    @Resource
    private ToolPartMapper toolPartMapper;

    @Resource
    private WarehouseRespository warehouseRespository;

    @Resource
    private MachineToolDataLogMapper machineToolDataLogMapper;

    @Resource
    private EquipmentGroupRepository equipmentGroupRepository;

    @Resource
    private InventoryLocationService inventoryLocationService;

    @Resource
    private ToolScheduleService toolScheduleService;

    @Resource
    private AssemblyToolInventoryMapper assemblyToolInventoryMapper;

    @Resource
    private AllotEmployeeRepository allotEmployeeRepository;

    @Resource
    private MachineToolTaskRespository machineToolTaskRespository;

    @Resource
    private InventoryLocationRespository inventoryLocationRespository;

    @Resource
    private MachineToolStatusMapper machineToolStatusMapper;

    @Resource
    private ProgramDurationTimeMapper programDurationTimeMapper;


    @Resource
    private MessageService messageService;

    @Resource
    private ConfigurationMapper configurationMapper;

    @Autowired
    private MqttHelper mqttHelper;

    //机床名和对应的sn号
    private static final HashMap<String, String> snMap = new HashMap<>();

    private static final String POSITION_KEY = "position";

    //计数内存map
    private static final ConcurrentHashMap<String, Integer> countMap = new ConcurrentHashMap<>();

    public static final ConcurrentHashMap<String, String> statusMap = new ConcurrentHashMap<>();

    //分组内存map
    private static final HashMap<Integer, String> groupMap = new HashMap<>();
    private static final HashMap<String, Boolean> groupMachineToolMap = new HashMap<>();

    //sn刀具内存map
    private static final ConcurrentHashMap<String, Double> toolLife1Map = new ConcurrentHashMap<>();

    private static final ConcurrentHashMap<String, Double> toolLifeMap = new ConcurrentHashMap<>();

    public static final ConcurrentHashMap<String, String> programMap = new ConcurrentHashMap<>();

    public static final ConcurrentHashMap<String, String> programCacheMap = new ConcurrentHashMap<>();

    //连接对象内存map
    private static ConcurrentHashMap<String, DeviceClient> clientMap = new ConcurrentHashMap<>();

    public static ConcurrentHashMap<String, Object> configurationMap = new ConcurrentHashMap<>();

    //public static final UserEntity user = new UserEntity();

    private static Long delay = 30000L;

    private static Integer retryCount = 0;


    static {
        snMap.put("B2", "1000E0DC000021");
        snMap.put("B3", "1000E0DC0001DB");
        snMap.put("B4", "1000E0DC00017E");
        snMap.put("B5", "1000E0DC0001BE");
        snMap.put("B6", "1000E0DC00025E");
        snMap.put("B11", "1000E0DC0001FB");
        snMap.put("B12", "1000E0DC0001DC");
        snMap.put("B13", "1000E0DC0001E1");
        snMap.put("B14", "1000E0DC000011");
        snMap.put("B15", "1000E0DC00022C");
        snMap.put("B16", "1000E0DC00016F");
        snMap.put("B17", "1000E0DC000246");

        groupMachineToolMap.put("1000E0DC0001FB", true);
        groupMachineToolMap.put("1000E0DC0001DC", true);
        groupMachineToolMap.put("1000E0DC000246", true);


//        countMap.put("B1", -1);
//        countMap.put("B2", -1);
//        countMap.put("B3", -1);
//        countMap.put("B4", -1);
//        countMap.put("B5", -1);
//        countMap.put("B6", -1);
//        countMap.put("B7", -1);
//        countMap.put("B8", -1);
//        countMap.put("B9", -1);
//        countMap.put("B10", -1);
//        countMap.put("B11", -1);
//        countMap.put("B12", -1);
//        countMap.put("B13", -1);
//        countMap.put("B14", -1);
//        countMap.put("B15", -1);
//        countMap.put("B16", -1);
        countMap.put("B17", -1);

    }


    /**
     * 定时拉取机床刀具参数
     */
//    @PostConstruct
//    public void schedulePullToolArgs(){
//        //countMap.forEach();
//        //开启定时任务线程池
//        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
//        scheduledThreadPool.scheduleAtFixedRate(() ->
//                        snMap.entrySet().forEach(nameSnEntry -> {
//                            try {
////                                DeviceClient deviceClient =
////                                        new DeviceClient(nameSnEntry.getValue(), "tcp://192.168.19.99:1883", null, null, null);
////
////                                deviceClient.connect();
//                                DeviceClient deviceClient = toolScheduleService.ConnectDevice(nameSnEntry.getValue());
//                                String id = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/TOOL_PARAM");
//                                int i = toolScheduleService.getLengthByGroup(warehouseRespository.getIdByName(nameSnEntry.getKey()), deviceClient, id);
////                                List<Object> length = deviceClient.easyQuery(3000, new QueryRequestItem.Builder().id(id).operation(Operation.GET_LENGTH).build());
////                                int i = Integer.parseInt(((List) length.get(0)).get(0).toString());
//                                //先Operation.GET_LENGTH取长度
//                                List<Object> result = deviceClient.easyQuery(2000, new QueryRequestItem.Builder()
//                                        .id(id).addIndexRange(0, i - 1).build());
//                                //List<Object> result = mqttHelper.getCurrentGFileLineNumber(nameSnEntry.getValue());
//                                if (ObjectUtil.isNotNull(result.get(0))) {
//                                    List<IncBoxParamVo> incBoxParamVos = CommonUtil.parseToolParams(result.get(0).toString());
//                                    //List<IncBoxParamVo> incBoxParamVos = JSONArray.parseArray(result.get(0).toString(), IncBoxParamVo.class);
//                                    incBoxParamVos = CommonUtil.filterBoxParamList(incBoxParamVos);
//                                    incBoxParamVos.forEach(incBoxParamVo -> {
//                                        if (ObjectUtil.isNotNull(incBoxParamVo)) {
//                                            LinkedHashMap<String, Object> key_value = incBoxParamVo.getKey_value();
//                                            String position = key_value.getOrDefault(POSITION_KEY, "").toString();
//                                            //刀具长度
//                                            //String toolLength = incBoxParamVo.getLength();
//                                            Double length = Double.valueOf(incBoxParamVo.getLength());
//                                            String lengthFormat = new DecimalFormat("######0.000").format(length);
//                                            Double toolLength = Double.valueOf(lengthFormat);
//                                            //刀具额定寿命参数
//                                            Integer toolLife = Integer.valueOf(incBoxParamVo.getMax_time_usage());
//                                            double toolLifeDouble = toolLife.doubleValue();
//                                            //刀具半径
//                                            Double radius = Double.valueOf(incBoxParamVo.getRadius());
//                                            String radiusFormat = new DecimalFormat("######0.000").format(radius);
//                                            Double toolRadius = Double.valueOf(radiusFormat);
//                                            //刀具号
//                                            String toolNo = "T" + incBoxParamVo.getName();
//                                            //刀具使用寿命参数（该机床）
//                                            Double toolUsageTime = Double.valueOf(incBoxParamVo.getTime_usage());
//                                            //保留两位小数点并四舍五入
//                                            String format = new DecimalFormat("######0.00").format(toolUsageTime);
//                                            Double toolUsageTimeSub = Double.valueOf(format);
//                                            //取到对应的位置信息以及
//                                            String uniqueId = "";
//                                            try{
//                                                uniqueId = getUniqueIdByToolParam(toolNo, lengthFormat, radiusFormat);
//                                            }catch (Exception e){
//                                                log.error(e.getMessage());
//                                            }
//                                            ToolPartEntity toolPartEntity = getToolPartEntity(position, nameSnEntry.getValue(), uniqueId);
//                                            updateToolLocation(nameSnEntry.getKey() , nameSnEntry.getValue(), position, toolNo, uniqueId, toolPartEntity);
//                                        }
//                                    });
//                                }
////                                deviceClient.close();
//                            } catch (Exception e) {
//                                System.out.println("e.getMessage() = " + e.getMessage());
//                                log.error("刀参数据采集错误: ->{}" + System.currentTimeMillis() + e.getMessage());
//                            }
//                        }),
//                10L,//延迟30秒执行
//                60L,//每隔60秒执行
//                TimeUnit.SECONDS);
//
//    }
    private void updateToolLocation(String warehouseName, String snCode, String position, String toolNo, String uniqueId, ToolPartEntity toolPartEntity) {
        if (ObjectUtil.isNotNull(toolPartEntity)) {
            //校验该总成库存位置
            List<Integer> locationIds = inventoryLocationRespository.queryByWarehouseName("备刀货架");
            if (CollectionUtil.isNotEmpty(locationIds)
                    && ObjectUtil.isNotNull(toolPartEntity.getInventoryLocationId())
                    && !locationIds.contains(toolPartEntity.getInventoryLocationId())) {
                return;
            }
            //updateLifeBySn(lengthFormat, radiusFormat, toolLife, toolLifeDouble, toolUsageTime, toolUsageTimeSub, toolPartEntity);
            QueryWrapper<AssemblyToolInventoryEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("tool_no", toolNo);
            AssemblyToolInventoryEntity assemblyToolInventoryEntity = assemblyToolInventoryMapper.selectOne(wrapper);
            if (ObjectUtil.isNotNull(assemblyToolInventoryEntity)) {
                //根据排班表查询机床负责人
                String operator = allotEmployeeRepository.selectMachineToolEmployee(getCurrentTime(), warehouseRespository.getByIdOrName(null, warehouseName).getId());
                if (ObjectUtil.isNotNull(toolPartEntity.getInventoryLocationId())
                        && toolPartEntity.getInventoryLocationId() != 0
                        && StringUtil.isNotEmpty(position)
                        && !toolPartEntity.getInventoryLocationId().equals(inventoryLocationRespository.queryIdByLocationNumAndSncode(position, snCode))) {
                    if (ObjectUtil.isNotNull(assemblyToolInventoryEntity)) {
                        //创建出库记录(唯一id出库)
                        OutboundUniqueAssemblyReq outboundUniqueAssemblyReq = new OutboundUniqueAssemblyReq();
                        UniqueAssemblyToolVo uniqueAssemblyToolVo = new UniqueAssemblyToolVo();
                        uniqueAssemblyToolVo.setToolNo(toolPartEntity.getToolNo());
                        uniqueAssemblyToolVo.setInventoryLocationId(toolPartEntity.getInventoryLocationId());
                        uniqueAssemblyToolVo.setId(toolPartEntity.getId());
                        uniqueAssemblyToolVo.setUniqueId(toolPartEntity.getUniqueId());
                        outboundUniqueAssemblyReq.setBatchAssemblyTool(Arrays.asList(uniqueAssemblyToolVo));
                        outboundUniqueAssemblyReq.setOperator(operator);
                        outboundUniqueAssemblyReq.setBz("");
                        try {
                            inventoryLocationService.outboundUniqueAssemblyTool(outboundUniqueAssemblyReq);
                        } catch (ToolLifeCycleException e) {
                            log.error("刀具出库记录添加异常: ->{}" + System.currentTimeMillis() + e.getMessage());
                        }
//                                                            OutBoundAssemblyReq outBoundAssemblyReq = new OutBoundAssemblyReq();
//                                                            outBoundAssemblyReq.setAssemblyToolInventoryId(assemblyToolInventoryEntity.getId());
//                                                            outBoundAssemblyReq.setNumber(1);
//                                                            outBoundAssemblyReq.setInventoryLocationId(toolPartEntity.getInventoryLocationId());
//                                                            outBoundAssemblyReq.setBz("");
//                                                            outBoundAssemblyReq.setOperator(operator);
//                                                            try {
//                                                                inventoryLocationService.outboundLocationAssemblyTool(outBoundAssemblyReq);
//                                                            } catch (ToolLifeCycleException e) {
//                                                                log.error("刀具出库记录添加异常: ->{}" + System.currentTimeMillis() + e.getMessage());
//                                                            }
                        //更新位置信息 生成对应入库记录
                        InboundAssemblyReq inboundAssemblyReq = new InboundAssemblyReq();
                        inboundAssemblyReq.setNumber(1);
                        inboundAssemblyReq.setOperator(operator);
                        inboundAssemblyReq.setLocationId(inventoryLocationRespository.queryIdByLocationNumAndSncode(position, snCode));
                        inboundAssemblyReq.setAssemblyUniqueId(uniqueId);
                        inboundAssemblyReq.setBz("");
                        //TO DO 更新后去掉备刀状态以及备刀工单字段
                        toolPartEntity.setBackupStatus(0);
                        toolPartEntity.setBackupMachineToolTaskId(0);
                        toolPartEntity.setSubprogramName("");
                        toolPartMapper.updateById(toolPartEntity);
                        try {
                            inventoryLocationService.inboundUniqueAssemblyTool(inboundAssemblyReq);
                        } catch (ToolLifeCycleException e) {
                            log.error("机床:" + warehouseName + "库位：" + position + "刀具入库记录添加异常: ->{}" + System.currentTimeMillis() + e.getMessage());

                        }
                    }
                }
            }
        }
    }

    private ToolPartEntity getToolPartEntity(String position, String scCode, String uniqueId) {
        //使用库位查找
        Integer inventoryLocationId = inventoryLocationRespository.queryIdByLocationNumAndSncode(position, scCode);
        ToolPartEntity toolPartEntity = toolPartRespository.getByLocationId(inventoryLocationId);
        if (ObjectUtil.isNotNull(toolPartEntity)) {
            return toolPartEntity;
        }
        return toolPartRespository.getByUniqueId(uniqueId);
    }

//    @PostConstruct
//    public void print() {
//        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
//        scheduledThreadPool.scheduleWithFixedDelay(() -> {
//                    List<ConfigurationEntity> existConfigurationEntities = configurationMapper.selectList(new QueryWrapper<>());
//                    if (CollectionUtil.isNotEmpty(existConfigurationEntities)) {
//                        List<String> coms = new ArrayList<>();
//                        List<String> shareFiles = new ArrayList<>();
//                        for (ConfigurationEntity configurationEntity : existConfigurationEntities) {
//                            if(configurationEntity.getConfigureKey().equals("com")){
//                                coms.add(configurationEntity.getConfigureValue());
//                            }
//                            if(configurationEntity.getConfigureKey().equals("shareFile")){
//                                shareFiles.add(configurationEntity.getConfigureValue());
//                            }
//                            configurationMap.put(configurationEntity.getConfigureKey(), configurationEntity.getConfigureValue());
//                        }
//                        if(CollectionUtil.isNotEmpty(coms)){
//                            configurationMap.put("com" , JSONArray.toJSONString(coms));
//                        }
//                        if(CollectionUtil.isNotEmpty(shareFiles)){
//                            configurationMap.put("shareFile" , JSONArray.toJSONString(shareFiles));
//                        }
//                    }
//                },
//                0,
//                2,
//                TimeUnit.HOURS);
//    }

//    @PostConstruct
//    public void pushMessage() {
//        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
//        scheduledThreadPool.scheduleAtFixedRate(() -> {
//                    messageService.unmetToolListMessage();
//                },
//                60L,//延迟30秒执行
//                60L,//每隔60秒执行
//                TimeUnit.SECONDS);
//    }


    private String getCurrentTime() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    /**
     * @param toolLength       (盒子采集的刀具长度)
     * @param toolRadius       (盒子采集的刀具半径)
     * @param toolLife         (盒子采集的刀具寿命)
     * @param toolLifeDouble   (刀盒子采集的具寿命浮点型)
     * @param toolUsageTime    (盒子采集的刀具使用寿命)
     * @param toolUsageTimeSub (数据库截取刀具使用寿命)
     * @param toolPartEntity   (sn确定的唯一刀具)
     */
    private void updateLifeBySn(String toolLength, String toolRadius, Integer toolLife, double toolLifeDouble, Double toolUsageTime, Double toolUsageTimeSub, ToolPartEntity toolPartEntity) {
        toolPartEntity.setRadius(toolRadius);
        toolPartEntity.setToolLength(toolLength);
        String uniqueId = toolPartEntity.getUniqueId();
        //处理读到的总成寿命
        List<ToolPartEntity> toolList = toolPartRespository.selectByAssemblyRFId(uniqueId);
        List<Double> toolLifeList = new ArrayList<>();
        toolList.forEach(toolEntity -> {
            toolEntity.setLife(toolLife + "h");
            if (StringUtil.isNotEmpty(toolEntity.getTimeUsage())) {
                //处理数据库中的刀具使用时间
                String timeUsage = toolEntity.getTimeUsage();
                Double existToolUsageTimeSub = Double.valueOf(timeUsage.substring(0, timeUsage.length() - 1));
                //如果数据库中刀具使用时长大于采集的使用时长，则相加
                //toolEntity.setTimeUsage(toolUsageTimeSub + "h");
                Double cacheTime = toolLife1Map.getOrDefault(uniqueId, 0.0);
                if (cacheTime - 0.0 <= 0.0) {
                    //为真表示第一次要加入内存map的值
                    toolLife1Map.put(uniqueId, toolUsageTimeSub);
                    cacheTime = toolUsageTimeSub;
                }
                if (toolUsageTimeSub >= cacheTime) {
                    Double gapTime = toolUsageTimeSub - cacheTime;
                    Double present = existToolUsageTimeSub + gapTime;
                    toolEntity.setTimeUsage(present + "h");
                    toolEntity.setRemainingLife((toolLifeDouble - present) + "h");
                    if ((toolLifeDouble - present) > 0) {
                        if (Math.round(toolLifeDouble - present) == 0) {
                            toolEntity.setRemainingLifeRate(Math.round((toolLifeDouble - present) * 100 / toolLifeDouble));
                        } else {
                            toolEntity.setRemainingLifeRate((long) 100);
                        }
                    } else {
                        toolEntity.setRemainingLifeRate((long) 100);
                    }
                } else {
                    Double present = existToolUsageTimeSub + toolUsageTimeSub;
                    toolEntity.setTimeUsage(present + "h");
                    toolEntity.setRemainingLife((toolLifeDouble - present) + "h");
                }
                toolLife1Map.put(uniqueId, toolUsageTimeSub);
            } else {
                toolEntity.setTimeUsage(toolUsageTimeSub + "h");
                toolEntity.setRemainingLife((toolLifeDouble - toolUsageTimeSub) + "h");
            }
            toolLifeList.add(Double.valueOf(toolEntity.getTimeUsage().substring(0, toolEntity.getTimeUsage().length() - 1)));
            toolPartMapper.updateById(toolEntity);
        });
        toolPartEntity.setLife(toolLife + "h");
        toolPartEntity.setTimeUsage(toolUsageTimeSub + "h");
        //设置总成寿命为寿命最小的刀片寿命
        toolPartEntity.setTimeUsage(CollectionUtil.min(toolLifeList) + "h");
        toolPartEntity.setRemainingLife((toolLife - CollectionUtil.min(toolLifeList)) + "h");
        try {
            toolPartEntity.setRemainingLifeRate(Math.round(toolLife - CollectionUtil.min(toolLifeList)) * 100 / toolLife);
        } catch (Exception e) {
            toolPartEntity.setRemainingLifeRate((long) 100);
            log.error(e.getMessage());
        }
        toolPartMapper.updateById(toolPartEntity);
    }


    /**
     * 根据库位获取唯一id
     */
    private String getUniqueIdByLocation(String warehouseName, String position) {
        return toolPartRespository.getByLocation(warehouseName, position);
    }

    /**
     * 根据刀号长度半径获取唯一id
     */
    private String getUniqueIdByToolParam(String toolNo, String length, String radius) {
        return ObjectUtil.isNotNull(toolPartRespository.getByToolParam(toolNo, length, radius)) ? toolPartRespository.getByToolParam(toolNo, length, radius) : toolNo + length + radius;
    }

    /**
     * 根据刀号长度获取唯一id
     */
    private String getUniqueIdByToolParamReload(String toolNo, String length, String radius) {
        return ObjectUtil.isNotNull(toolPartRespository.getByToolParamReload(toolNo, length)) ? toolPartRespository.getByToolParamReload(toolNo, length) : toolNo + length + radius;
    }

    public DeviceClient ConnectDevice(String sn) throws InvalidException, MqttException {
        DeviceClient ret = clientMap.get(sn);
        if (ret != null) {
            if (!ret.isConnected())
                if (!ret.connect()) {
                    ret = null;
                }

        }
        if (ret == null) {
            DeviceClient deviceClient = new DeviceClient(sn, "tcp://192.168.19.99:1883", null, null,
                    null);
            if (deviceClient != null || !deviceClient.isConnected()) {
                deviceClient.connect();
            }
            ret = deviceClient;
            clientMap.put(sn, deviceClient);
        }
        return ret;
    }

    /**
     * 定时拉取机床刀具参数
     */
//    @PostConstruct
//    public void updateDataLog() {
//        List<WarehouseSnVo> warehouseSnVos = warehouseRespository.selectWarehouseSnVo();
//        Map<Integer, String> warehouseSnMap = new HashMap<>();
//        if (CollectionUtil.isNotEmpty(warehouseSnVos)) {
//            List<MachineToolDataLog> insertList = new ArrayList<>();
//            warehouseSnVos.forEach(warehouseSnVo -> {
//
//                //初始化机床snMap
//                warehouseSnMap.put(warehouseSnVo.getWarehouseId(), warehouseSnVo.getSnCode());
//                System.out.println("warehouseSnVo = " + warehouseSnMap);
//                //初始化机床分组map
//                groupMap.put(warehouseSnVo.getWarehouseId(), equipmentGroupRepository.selectGroupTypeByEquipmentId(warehouseSnVo.getWarehouseId()));
//
//                //初始化刀具寿命map
//                try {
//                    DeviceClient deviceClient = toolScheduleService.ConnectDevice(warehouseSnVo.getSnCode());
////                    deviceClient.connect();
//                    //获取刀具参数
//                    String toolParamId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/TOOL_PARAM");
//                    int i = toolScheduleService.getLengthByGroup(warehouseSnVo.getWarehouseId(), deviceClient, toolParamId);
//                    List<Object> result = deviceClient.easyQuery(3000, new QueryRequestItem.Builder()
//                            .id(toolParamId).addIndexRange(0, i - 1).build());
//
//                    //获取程序
//                    String programId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/PROGRAM");
//                    List<?> o = deviceClient.easyQuery(3000,
//                            new QueryRequestItem.Builder().id(programId).operation(Operation.GET_VALUE).build());
//
//                    String programName = "";
//                    if (CollectionUtil.isNotEmpty(o) && ObjectUtil.isNotNull(o.get(0))) {
//                        programName = CommonUtil.getProgramString(o);
//                        programCacheMap.put(warehouseSnVo.getSnCode() , programName);
//                    }
//
//                    if (ObjectUtil.isNotNull(result.get(0))) {
//                        List<IncBoxParamVo> incBoxParamVos = CommonUtil.parseToolParams(result.get(0).toString());
//                        incBoxParamVos = CommonUtil.filterBoxParamList(incBoxParamVos);
//                        incBoxParamVos.forEach(incBoxParamVo -> {
//                            if (ObjectUtil.isNotNull(incBoxParamVo)) {
//                                LinkedHashMap<String, Object> key_value = incBoxParamVo.getKey_value();
//                                //刀具额定寿命参数
//                                Integer toolLife = Integer.valueOf(incBoxParamVo.getMax_time_usage());
//                                double toolLifeDouble = toolLife.doubleValue();
//                                //刀具使用寿命参数（该机床）
//                                Double toolUsageTime = Double.valueOf(incBoxParamVo.getTime_usage());
//                                //保留两位小数点并四舍五入
//                                String format = new DecimalFormat("######0.00").format(toolUsageTime);
//                                Double toolUsageTimeSub = Double.valueOf(format);
//                                //存入内存map
//                                //刀具长度
//                                Double length = Double.valueOf(incBoxParamVo.getLength());
//                                String lengthFormat = new DecimalFormat("######0.000").format(length);
//                                Double toolLength = Double.valueOf(lengthFormat);
//                                //刀具号
//                                String toolNo = "T" + incBoxParamVo.getName();
//                                String position = key_value.getOrDefault(POSITION_KEY, "").toString();
//                                //刀具半径
//                                Double radius = Double.valueOf(incBoxParamVo.getRadius());
//                                String radiusFormat = new DecimalFormat("######0.000").format(radius);
//                                Double toolRadius = Double.valueOf(radiusFormat);
//
//                                //取到对应的位置信息以及
//                                String uniqueId = "";
//                                try{
//                                    uniqueId = getUniqueIdByToolParam(toolNo, lengthFormat, radiusFormat);
//                                }
//                                catch (Exception e){
//                                    log.error(e.getMessage());
//                                }
//                                if (StringUtil.isNotEmpty(uniqueId)) {
//                                    ToolPartEntity toolPartEntity = getToolPartEntity(position, warehouseSnVo.getSnCode(), uniqueId);
//                                    toolLifeMap.put(uniqueId, toolUsageTimeSub);
//                                    MachineToolDataLog machineToolDataLog = new MachineToolDataLog();
//                                    machineToolDataLog.setRfid(toolNo + toolLength + toolRadius);
//                                    machineToolDataLog.setCreateTime(new Date());
//                                    machineToolDataLog.setPosition(position);
//                                    machineToolDataLog.setToolLife(toolLifeDouble);
//                                    machineToolDataLog.setWarehouseId(warehouseSnVo.getWarehouseId());
//                                    machineToolDataLog.setWarehouseName(warehouseRespository.getNameByWarehouseId(warehouseSnVo.getWarehouseId()));
//                                    machineToolDataLog.setLength(toolLength + "");
//                                    machineToolDataLog.setTime(toolUsageTimeSub);
//                                    machineToolDataLog.setUniqueId(uniqueId);
//                                    machineToolDataLog.setToolNo(toolNo);
//                                    machineToolDataLog.setToolRadius(toolRadius + "");
//                                    machineToolDataLog.setToolUsageTime(toolUsageTimeSub);
//                                    if(ObjectUtil.isNotNull(toolPartEntity)){
//                                        machineToolDataLog.setToolParams(toolPartEntity.getParams());
//                                        updateLifeBySnReload(lengthFormat ,radiusFormat ,toolLife , toolLifeDouble, toolUsageTimeSub , toolPartEntity , "");
//                                    }
//                                    insertList.add(machineToolDataLog);
//                                }
//                            }
//                        });
//                    }
////                    deviceClient.close();
//                } catch (Exception e) {
//                    log.error("刀参数据采集错误: ->{}" + System.currentTimeMillis() + e.getMessage());
//                }
//            });
//            if (CollectionUtil.isNotEmpty(insertList)) {
//                machineToolDataLogMapper.insertBatchSomeColumn(insertList);
//            }
//        }
//
//        try {
//            Thread.sleep(10000L);
//        } catch (InterruptedException e) {
//            log.error(e.getMessage());
//        }
//
//        Thread thread1 = new Thread(() -> {
//            while (true) {
//                try {
//                    Thread.sleep(120000L);
//                } catch (InterruptedException e) {
//                    log.error(e.getMessage());
//                }
//                taskReload(warehouseSnMap);
//            }
//        });
//
//        //初始化机床状态
//        initMachineToolStatus();
//
//        try {
//            Thread.sleep(10000L);
//        } catch (InterruptedException e) {
//            log.error(e.getMessage());
//        }
//
//        Thread thread13 = new Thread(() -> {
//            while (true) {
//                try {
//                    Thread.sleep(10000L);
//                } catch (InterruptedException e) {
//                    log.error(e.getMessage());
//                }
//                saveMachineToolStatusTask();
//                //task("1000E0DC00022C",38);
//            }
//        });
//
//        thread1.start();
////        thread13.start();
//    }


    /**
     * 单线程循环操作
     */
    private void taskReload(Map<Integer, String> snCodeMachineToolIdMap) {
        if (CollectionUtil.isNotEmpty(snCodeMachineToolIdMap)) {
            snCodeMachineToolIdMap.forEach((machineToolId, snCode) -> {
                List<MachineToolDataLog> insertList = new ArrayList<>();
                try {
                    DeviceClient deviceClient = toolScheduleService.ConnectDevice(snCode);

                    //获取程序
                    String programId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/PROGRAM");
                    List<?> o = deviceClient.easyQuery(3000,
                            new QueryRequestItem.Builder().id(programId).operation(Operation.GET_VALUE).build());

                    //获取进给速度
                    String feedSpeedId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/FEED_SPEED");
                    List<?> feedSpeed = deviceClient.easyQuery(3000,
                            new QueryRequestItem.Builder().id(feedSpeedId).operation(Operation.GET_VALUE).build());

                    //获取程序
                    String feedOverrideId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/FEED_OVERRIDE");
                    List<?> feedOverride = deviceClient.easyQuery(3000,
                            new QueryRequestItem.Builder().id(feedOverrideId).operation(Operation.GET_VALUE).build());

                    //获取刀具参数
                    String toolParamId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/TOOL_PARAM");
                    int i = toolScheduleService.getLengthByGroup(machineToolId, deviceClient, toolParamId);
                    //先Operation.GET_LENGTH取长度
                    List<Object> result = deviceClient.easyQuery(7000, new QueryRequestItem.Builder()
                            .id(toolParamId).addIndexRange(0, i - 1).build());
                    //List<Object> result = mqttHelper.getCurrentGFileLineNumber(nameSnEntry.getValue());
                    if (ObjectUtil.isNotNull(result.get(0))) {
                        List<IncBoxParamVo> incBoxParamVos = CommonUtil.parseToolParams(result.get(0).toString());
                        incBoxParamVos = CommonUtil.filterBoxParamList(incBoxParamVos);
                        incBoxParamVos.forEach(incBoxParamVo -> {
                            if (ObjectUtil.isNotNull(incBoxParamVo)) {
                                MachineToolDataLog machineToolDataLog = new MachineToolDataLog();
                                LinkedHashMap<String, Object> key_value = incBoxParamVo.getKey_value();
                                //刀具长度
                                Double length = Double.valueOf(incBoxParamVo.getLength());
                                String lengthFormat = new DecimalFormat("######0.000").format(length);
                                Double toolLength = Double.valueOf(lengthFormat);
                                //刀具额定寿命参数
                                Integer toolLife = Integer.valueOf(incBoxParamVo.getMax_time_usage());
                                double toolLifeDouble = toolLife.doubleValue();
                                //刀具半径
                                Double radius = Double.valueOf(incBoxParamVo.getRadius());
                                String radiusFormat = new DecimalFormat("######0.000").format(radius);
                                Double toolRadius = Double.valueOf(radiusFormat);
                                //刀具号
                                String toolNo = "T" + incBoxParamVo.getName();
                                //刀具使用寿命参数（该机床）
                                Double toolUsageTime = Double.valueOf(incBoxParamVo.getTime_usage());
                                //保留两位小数点并四舍五入
                                String format = new DecimalFormat("######0.000").format(toolUsageTime);
                                Double toolUsageTimeSub = Double.valueOf(format);
                                //取到对应的位置信息以及
                                String position = key_value.getOrDefault(POSITION_KEY, "").toString();
                                String uniqueId = getUniqueIdByToolParam(toolNo, lengthFormat, radiusFormat);
                                ToolPartEntity toolPartEntity = getToolPartEntity(position, snCode, uniqueId);

                                if (ObjectUtil.isNotNull(toolPartEntity)) {
                                    uniqueId = toolPartEntity.getUniqueId();
                                    machineToolDataLog.setToolParams(toolPartEntity.getParams());
                                }

                                //更新刀具库位
                                String machineToolName = warehouseRespository.getNameByWarehouseId(machineToolId);
                                if (ObjectUtil.isNotNull(toolPartEntity)) {
                                    updateToolLocation(machineToolName, snCode, position, toolNo, uniqueId, toolPartEntity);
                                }

                                //获取当前时间当前机床加工的
                                List<MachineToolTaskEntity> machineToolTaskEntities = machineToolTaskRespository.queryCurrentTaskId(new Date(), machineToolId);
                                if (CollectionUtil.isNotEmpty(machineToolTaskEntities)) {
                                    MachineToolTaskEntity machineToolTask = new MachineToolTaskEntity();
                                    List<MachineToolTaskEntity> collect = machineToolTaskEntities.stream().filter(machineToolTaskEntity ->
                                            ObjectUtil.isNotNull(machineToolTaskEntity.getActualStartTime()) && ObjectUtil.isNull(machineToolTaskEntity.getActualEndTime())
                                    ).collect(Collectors.toList());
                                    if (CollectionUtil.isNotEmpty(collect)) {
                                        machineToolTask = collect.get(0);
                                        machineToolDataLog.setMachineToolTaskId(machineToolTask.getId());
                                        machineToolDataLog.setTaskId(machineToolTask.getOrderTaskId());
                                        machineToolDataLog.setSeq(machineToolTask.getOrderSnapshotCraftSeq());
                                        machineToolDataLog.setCraftName(machineToolTask.getCraftName());
                                        machineToolDataLog.setStartTime(machineToolTask.getStartTime());
                                        machineToolDataLog.setEndTime(machineToolTask.getEndTime());
                                        //实际加工时间范围标志位
                                        machineToolDataLog.setFlag(1);
                                    } else {
                                        List<MachineToolTaskEntity> collect1 = machineToolTaskEntities.stream().filter(machineToolTaskEntity -> {
                                                    Date date = new Date();
                                                    return machineToolTaskEntity.getStartTime().compareTo(date) < 0 && machineToolTaskEntity.getEndTime().compareTo(date) > 0;
                                                }
                                        ).collect(Collectors.toList());
                                        if (CollectionUtil.isNotEmpty(collect1)) {
                                            machineToolTask = collect1.get(0);
                                            machineToolDataLog.setMachineToolTaskId(machineToolTask.getId());
                                            machineToolDataLog.setTaskId(machineToolTask.getOrderTaskId());
                                            machineToolDataLog.setSeq(machineToolTask.getOrderSnapshotCraftSeq());
                                            machineToolDataLog.setCraftName(machineToolTask.getCraftName());
                                            machineToolDataLog.setStartTime(machineToolTask.getStartTime());
                                            machineToolDataLog.setEndTime(machineToolTask.getEndTime());
                                            //实际加工时间范围标志位
                                            machineToolDataLog.setFlag(0);
                                        }
                                    }
                                }
                                machineToolDataLog.setRfid(toolNo + toolLength + toolRadius);
                                machineToolDataLog.setCreateTime(new Date());
                                machineToolDataLog.setPosition(position);
                                machineToolDataLog.setToolLife(toolLifeDouble);
                                machineToolDataLog.setWarehouseId(machineToolId);
                                machineToolDataLog.setWarehouseName(machineToolName);
                                machineToolDataLog.setLength(toolLength + "");
                                machineToolDataLog.setUniqueId(uniqueId);
                                machineToolDataLog.setToolNo(toolNo);
                                machineToolDataLog.setToolRadius(toolRadius + "");
                                machineToolDataLog.setToolUsageTime(toolUsageTimeSub);
                                if (CollectionUtil.isNotEmpty(o) && ObjectUtil.isNotNull(o.get(0))) {
                                    machineToolDataLog.setProgram(CommonUtil.getProgramString(o));
                                }
                                if (!groupMachineToolMap.getOrDefault(snCode, false) && ObjectUtil.isNotNull(CommonUtil.getProgramString(feedSpeed))) {
                                    machineToolDataLog.setFeedSpeed(CommonUtil.getProgramString(feedSpeed));
                                }
                                if (ObjectUtil.isNotNull(CommonUtil.getProgramString(feedOverride))) {
                                    machineToolDataLog.setFeedOverride(CommonUtil.getProgramString(feedOverride));
                                }
                                Double cacheTime = toolLifeMap.get(uniqueId);
                                //如果大于0那么
                                if (ObjectUtil.isNotNull(cacheTime)) {
                                    if ((toolUsageTimeSub - cacheTime > 0.00000)) {
                                        machineToolDataLog.setTime(toolUsageTimeSub - cacheTime);
                                        if (BigDecimal.valueOf(machineToolDataLog.getTime()).compareTo(BigDecimal.ZERO) != 0) {
                                            //采用程序内存map中的程序名称并更新程序内存map
                                            String currentProgramName = machineToolDataLog.getProgram();
                                            if(ObjectUtil.isNotNull(programCacheMap.get(snCode))){
                                                machineToolDataLog.setProgram(programCacheMap.get(snCode));
                                            }
                                            programCacheMap.put(snCode , currentProgramName);
                                            //updateLifeBySnReload(lengthFormat ,radiusFormat ,toolLife , toolLifeDouble, machineToolDataLog.getTime() , toolPartEntity);
                                            //updateLifeBySnReload1(lengthFormat ,radiusFormat ,toolLife ,machineToolDataLog.getTime()  , toolUsageTimeSub , toolPartEntity , machineToolName);
                                            updateLifeBySnReload(lengthFormat, radiusFormat, toolLife, toolLifeDouble, machineToolDataLog.getTime(), toolPartEntity, machineToolName);
                                            insertList.add(machineToolDataLog);
                                        }
                                    }
                                } else {
                                    //内存map中没有 第一次初始化
                                    //updateLifeBySnReload1(lengthFormat ,radiusFormat ,toolLife , toolUsageTimeSub, toolUsageTimeSub , toolPartEntity , machineToolName);
                                    updateLifeBySnReload(lengthFormat, radiusFormat, toolLife, toolLifeDouble, toolUsageTimeSub, toolPartEntity, machineToolName);
                                    machineToolDataLog.setTime(toolUsageTimeSub);
                                    programCacheMap.put(snCode , machineToolDataLog.getProgram());
                                    insertList.add(machineToolDataLog);
                                }
                                toolLifeMap.put(uniqueId, toolUsageTimeSub);
                            }
                        });
                        if (CollectionUtil.isNotEmpty(insertList)) {
                            machineToolDataLogMapper.insertBatchSomeColumn(insertList);
                        }
                    }
                } catch (Exception e) {
                    log.error("刀参数据采集错误: ->{}" + System.currentTimeMillis() + e.getMessage());
                }
            });
        }
    }

    /**
     * @param toolLength     (盒子采集的刀具长度)
     * @param toolRadius     (盒子采集的刀具半径)
     * @param toolLife       (盒子采集的刀具寿命)
     * @param toolPartEntity (sn确定的唯一刀具)
     */
    private void updateLifeBySnReload(String toolLength, String toolRadius, Integer toolLife, Double toolLifeDouble, Double gapTime, ToolPartEntity toolPartEntity, String machineToolName) {
        if (ObjectUtil.isNull(toolPartEntity)) {
            return;
        }
//        toolPartEntity.setRadius(toolRadius);
//        toolPartEntity.setToolLength(toolLength);
        String uniqueId = toolPartEntity.getUniqueId();
        //处理读到的总成寿命
        List<ToolPartEntity> toolList = toolPartRespository.selectByAssemblyRFId(uniqueId);
        List<Double> toolLifeList = new ArrayList<>();
        toolList.forEach(toolEntity -> {
            toolEntity.setLife(toolLife + "h");
            if (StringUtil.isNotEmpty(toolEntity.getTimeUsage())) {
                //处理数据库中的刀具使用时间
                String timeUsage = toolEntity.getTimeUsage();
                Double existToolUsageTimeSub = Double.valueOf(timeUsage.substring(0, timeUsage.length() - 1));
                Double present = existToolUsageTimeSub + gapTime;
                buildTimeDataLog(toolEntity, gapTime, present, "");
                //相加间隔时间
                toolEntity.setSummationTime(existToolUsageTimeSub + gapTime + "h");
                toolEntity.setTimeUsage(existToolUsageTimeSub + gapTime + "h");
                toolEntity.setRemainingLife((toolLife - present) + "h");
                try {
                    toolEntity.setRemainingLifeRate(Math.round((toolLifeDouble - present) * 100 / toolLifeDouble));
                } catch (Exception e) {
                    toolEntity.setRemainingLifeRate((long) 100);
                    log.error(e.getMessage());
                }
            } else {
                toolEntity.setSummationTime(gapTime + "h");
                toolEntity.setTimeUsage(gapTime + "h");
                toolEntity.setRemainingLife((toolLife - gapTime) + "h");
                try {
                    toolEntity.setRemainingLifeRate(Math.round((toolLifeDouble - gapTime) * 100 / toolLifeDouble));
                } catch (Exception e) {
                    toolEntity.setRemainingLifeRate((long) 100);
                    log.error(e.getMessage());
                }
            }
            toolLifeList.add(Double.valueOf(toolEntity.getTimeUsage().substring(0, toolEntity.getTimeUsage().length() - 1)));
            toolPartMapper.updateById(toolEntity);
        });
        toolPartEntity.setLife(toolLife + "h");
        //设置总成寿命为寿命最小的刀片寿命
        toolPartEntity.setSummationTime(CollectionUtil.min(toolLifeList) + "h");
        toolPartEntity.setTimeUsage(CollectionUtil.min(toolLifeList) + "h");
        toolPartEntity.setRemainingLife((toolLife - CollectionUtil.min(toolLifeList)) + "h");
        try {
            toolPartEntity.setRemainingLifeRate(Math.round(toolLife - CollectionUtil.min(toolLifeList)) * 100 / toolLife);
        } catch (Exception e) {
            toolPartEntity.setRemainingLifeRate((long) 100);
            log.error(e.getMessage());
        }
        toolPartMapper.updateById(toolPartEntity);
    }


    /**
     * @param toolLength     (盒子采集的刀具长度)
     * @param toolRadius     (盒子采集的刀具半径)
     * @param toolLife       (盒子采集的刀具寿命)
     * @param toolPartEntity (sn确定的唯一刀具)
     */
    private void updateLifeBySnReload1(String toolLength, String toolRadius, Integer toolLife, Double gapTime, Double timeUsage, ToolPartEntity toolPartEntity, String machineToolName) {
        if (ObjectUtil.isNull(toolPartEntity)) {
            return;
        }
        toolPartEntity.setRadius(toolRadius);
        toolPartEntity.setToolLength(toolLength);
        String uniqueId = toolPartEntity.getUniqueId();
        //处理读到的总成寿命
        List<ToolPartEntity> toolList = toolPartRespository.selectByAssemblyRFId(uniqueId);
        List<Double> toolLifeList = new ArrayList<>();
        toolList.forEach(toolEntity -> {
            toolEntity.setLife(toolLife + "h");
            buildTimeDataLog(toolEntity, gapTime, timeUsage, machineToolName);
//            if (StringUtil.isNotEmpty(toolEntity.getTimeUsage())) {
//                //处理数据库中的刀具使用时间
//                String timeUsage = toolEntity.getTimeUsage();
//                Double existToolUsageTimeSub = Double.valueOf(timeUsage.substring(0, timeUsage.length() - 1));
//                Double present = existToolUsageTimeSub + gapTime;
//                //相加间隔时间
//                toolEntity.setTimeUsage(existToolUsageTimeSub + gapTime + "h");
//                toolEntity.setRemainingLife((toolLife - present) + "h");
//                try{
//                    toolEntity.setRemainingLifeRate(Math.round((toolLifeDouble - present)  * 100 / toolLifeDouble));
//                }catch (Exception e){
//                    toolEntity.setRemainingLifeRate((long) 100);
//                    log.error(e.getMessage());
//                }
//            } else {
//                toolEntity.setTimeUsage(gapTime + "h");
//                toolEntity.setRemainingLife((toolLife - gapTime) + "h");
//                try{
//                    toolEntity.setRemainingLifeRate(Math.round((toolLifeDouble - gapTime)  * 100 / toolLifeDouble));
//                }catch (Exception e){
//                    toolEntity.setRemainingLifeRate((long) 100);
//                    log.error(e.getMessage());
//                }
//            }
            toolEntity.setRemainingLifeRate(Math.round((toolLife - gapTime) * 100 / toolLife));
            toolEntity.setTimeUsage(timeUsage + "h");
            //toolLifeList.add(Double.valueOf(toolEntity.getTimeUsage().substring(0, toolEntity.getTimeUsage().length() - 1)));
            toolLifeList.add(timeUsage);
            toolPartMapper.updateById(toolEntity);
        });
        toolPartEntity.setLife(toolLife + "h");
        //设置总成寿命为寿命最小的刀片寿命
        toolPartEntity.setTimeUsage(CollectionUtil.min(toolLifeList) + "h");
        toolPartEntity.setRemainingLife((toolLife - CollectionUtil.min(toolLifeList)) + "h");
        try {
            toolPartEntity.setRemainingLifeRate(Math.round(toolLife - CollectionUtil.min(toolLifeList)) * 100 / toolLife);
        } catch (Exception e) {
            toolPartEntity.setRemainingLifeRate((long) 100);
            log.error(e.getMessage());
        }
        toolPartMapper.updateById(toolPartEntity);
    }

    private void buildTimeDataLog(ToolPartEntity toolPartEntity, Double gapTime, Double timeUsage, String machineToolName) {
        AddTimeDataLogVo addTimeDataLogVo = new AddTimeDataLogVo();
        addTimeDataLogVo.setTime(gapTime);
        addTimeDataLogVo.setMachineToolName(machineToolName);
        addTimeDataLogVo.setCreateTime(new Date());
        addTimeDataLogVo.setExistTimeUsage(toolPartEntity.getTimeUsage());
        addTimeDataLogVo.setPresent(timeUsage);
        if (StringUtil.isEmpty(toolPartEntity.getDataLog()) || "[]".equals(toolPartEntity.getDataLog())) {
            //之前无装配记录
            List<AddTimeDataLogVo> list = new ArrayList<>();
            list.add(addTimeDataLogVo);
            toolPartEntity.setDataLog(JSONArray.toJSONString(list));
            return;
        }
        //之前有装配记录
        List<AddTimeDataLogVo> assembleLogVos = JSONArray.parseArray(toolPartEntity.getDataLog(), AddTimeDataLogVo.class);
        assembleLogVos.add(addTimeDataLogVo);
        toolPartEntity.setDataLog(JSONArray.toJSONString(assembleLogVos));
    }


    /**
     * 根据机床id判断计件数是否变化
     *
     * @param deviceClient
     * @param key
     * @return
     * @throws MqttException
     * @throws InvalidRequestException
     * @throws TimeoutException
     * @throws InvalidIdException
     * @throws InvalidMessageException
     * @throws InvalidItemException
     */
    private boolean getPartCount(DeviceClient deviceClient, Integer key) throws Exception {
        String equipmentGroup = groupMap.getOrDefault(key, "");
        //西门子机床通过计件数接口来处理
        if (StringUtil.isNotEmpty(equipmentGroup)) {
            switch (equipmentGroup) {
                case "西门子":
                    String partCountId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/PART_COUNT");
                    //先Operation.GET_LENGTH取长度
                    Object o = deviceClient.easyQuery(3000, new QueryRequestItem.Builder()
                            .id(partCountId).operation(Operation.GET_VALUE).build());
                    Integer partCount = CommonUtil.getPartCount(o);
                    if (ObjectUtil.isNull(countMap.get(warehouseRespository.getNameByWarehouseId(key)))) {
                        //为空直接返回false
                        return false;
                    }
                    //不为空判断是否发生变化
                    if (partCount.equals(countMap.get(warehouseRespository.getNameByWarehouseId(key)))) {
                        //计件数无变化
                        return false;
                    }
                    //计件数变化，更加内存map中对应的计件数
                    countMap.put(warehouseRespository.getNameByWarehouseId(key), partCount);
                    return true;
                //TO DO 根据不同类型做不同处理
                case "科德":
                    return false;
                case "海德汉":
                    return false;
                case "":
                    return false;
            }
        }
        return false;
    }


//    public void updateDataLogTest() {
//        List<WarehouseSnVo> warehouseSnVos = warehouseRespository.selectWarehouseSnVo();
//        Map<Integer, String> warehouseSnMap = new HashMap<>();
//        if (CollectionUtil.isNotEmpty(warehouseSnVos)) {
//            warehouseSnVos.forEach(warehouseSnVo -> {
//
//                //初始化机床snMap
//                warehouseSnMap.put(warehouseSnVo.getWarehouseId(), warehouseSnVo.getSnCode());
//                //初始化机床分组map
//                groupMap.put(warehouseSnVo.getWarehouseId(), equipmentGroupRepository.selectGroupTypeByEquipmentId(warehouseSnVo.getWarehouseId()));
//
//                //初始化刀具寿命map
//                try {
//                    DeviceClient deviceClient = toolScheduleService.ConnectDevice(warehouseSnVo.getSnCode());
////                    deviceClient.connect();
//                    //获取刀具参数
//                    String toolParamId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/TOOL_PARAM");
//                    int i = toolScheduleService.getLengthByGroup(warehouseSnVo.getWarehouseId(), deviceClient, toolParamId);
//                    List<Object> result = deviceClient.easyQuery(3000, new QueryRequestItem.Builder()
//                            .id(toolParamId).addIndexRange(0, i - 1).build());
//                    if (ObjectUtil.isNotNull(result.get(0))) {
//                        List<IncBoxParamVo> incBoxParamVos = CommonUtil.parseToolParams(result.get(0).toString());
//                        incBoxParamVos = CommonUtil.filterBoxParamList(incBoxParamVos);
//                        incBoxParamVos.forEach(incBoxParamVo -> {
//                            if (ObjectUtil.isNotNull(incBoxParamVo)) {
//                                //刀具使用寿命参数（该机床）
//                                Double toolUsageTime = Double.valueOf(incBoxParamVo.getTime_usage());
//                                //保留两位小数点并四舍五入
//                                String format = new DecimalFormat("######0.00").format(toolUsageTime);
//                                Double toolUsageTimeSub = Double.valueOf(format);
//                                //存入内存map
//                                //刀具长度
//                                //String toolLength = incBoxParamVo.getLength();
//                                String lengthFormat = new DecimalFormat("######0.000").format(incBoxParamVo.getRadius());
//                                Double toolLength = Double.valueOf(lengthFormat);
//                                //刀具号
//                                String toolNo = "T" + incBoxParamVo.getName();
//                                //刀具半径
//                                //String toolRadius = incBoxParamVo.getRadius();
//                                String radiusFormat = new DecimalFormat("######0.000").format(incBoxParamVo.getRadius());
//                                Double toolRadius = Double.valueOf(radiusFormat);
//                                //取到对应的位置信息以及
//                                String uniqueId = getUniqueIdByToolParam(toolNo, toolLength, toolRadius);
//                                if (StringUtil.isNotEmpty(uniqueId)) {
//                                    toolLifeMap.put(uniqueId, toolUsageTimeSub);
//                                }
//                            }
//                        });
//                    }
//                } catch (Exception e) {
//                    log.error("刀参数据采集错误: ->{}" + System.currentTimeMillis() + e.getMessage());
//                }
//            });
//
//        }
//        List<MachineToolDataLog> insertList = new ArrayList<>();
//        warehouseSnMap.entrySet().forEach(idSnEntry -> {
//            try {
//                DeviceClient deviceClient = toolScheduleService.ConnectDevice(idSnEntry.getValue());
//                //获取当前机床计件数并更新到内存map
//                boolean flag = getPartCount(deviceClient, idSnEntry.getKey());
//                if (flag) {
//                    return;
//                }
//
//                //获取程序
//                String programId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/PROGRAM");
//                Object o = deviceClient.easyQuery(3000,
//                        new QueryRequestItem.Builder().id(programId).operation(Operation.GET_VALUE).build());
//
//                //获取刀具参数
//                String toolParamId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/TOOL_PARAM");
//                int i = toolScheduleService.getLengthByGroup(idSnEntry.getKey(), deviceClient, toolParamId);
//                //先Operation.GET_LENGTH取长度
//                List<Object> result = deviceClient.easyQuery(3000, new QueryRequestItem.Builder()
//                        .id(toolParamId).addIndexRange(0, i - 1).build());
//
//                //List<Object> result = mqttHelper.getCurrentGFileLineNumber(nameSnEntry.getValue());
//                if (ObjectUtil.isNotNull(result.get(0))) {
//                    List<IncBoxParamVo> incBoxParamVos = CommonUtil.parseToolParams(result.get(0).toString());
//                    incBoxParamVos = CommonUtil.filterBoxParamList(incBoxParamVos);
//                    incBoxParamVos.forEach(incBoxParamVo -> {
//                        if (ObjectUtil.isNotNull(incBoxParamVo)) {
//                            MachineToolDataLog machineToolDataLog = new MachineToolDataLog();
//                            LinkedHashMap<String, Object> key_value = incBoxParamVo.getKey_value();
//                            //刀具长度
//                            Double length = Double.valueOf(incBoxParamVo.getLength());
//                            String lengthFormat = new DecimalFormat("######0.000").format(length);
//                            Double toolLength = Double.valueOf(lengthFormat);
//                            //刀具额定寿命参数
//                            Integer toolLife = Integer.valueOf(incBoxParamVo.getMax_time_usage());
//                            double toolLifeDouble = toolLife.doubleValue();
//                            //刀具半径
//                            Double radius = Double.valueOf(incBoxParamVo.getRadius());
//                            String radiusFormat = new DecimalFormat("######0.000").format(radius);
//                            Double toolRadius = Double.valueOf(radiusFormat);
//                            //刀具号
//                            String toolNo = "T" + incBoxParamVo.getName();
//                            //刀具使用寿命参数（该机床）
//                            Double toolUsageTime = Double.valueOf(incBoxParamVo.getTime_usage());
//                            //保留两位小数点并四舍五入
//                            String format = new DecimalFormat("######0.00").format(toolUsageTime);
//                            Double toolUsageTimeSub = Double.valueOf(format);
//                            //取到对应的位置信息以及
//                            String position = key_value.getOrDefault(POSITION_KEY, "").toString();
//                            String uniqueId = getUniqueIdByToolParam(toolNo, toolLength, toolRadius);
//                            MachineToolTaskEntity machineToolTaskEntity = machineToolTaskRespository.queryCurrentTaskId(new Date(), idSnEntry.getKey());
//                            Double cacheTime = toolLifeMap.get(uniqueId);
//                            System.out.println("toolLifeMap = " + toolLifeMap);
//                            if (ObjectUtil.isNotNull(cacheTime)) {
//                                machineToolDataLog.setTime(toolUsageTimeSub - cacheTime);
//                                if (ObjectUtil.isNotNull(machineToolTaskEntity)
//                                        && ObjectUtil.isNotNull(toolUsageTimeSub)
//                                        && ObjectUtil.isNotNull(cacheTime)
//                                        && !toolUsageTimeSub.equals(cacheTime)) {
//                                    machineToolDataLog.setMachineToolTaskId(machineToolTaskEntity.getId());
//                                    machineToolDataLog.setTaskId(machineToolTaskEntity.getOrderTaskId());
//                                    machineToolDataLog.setSeq(machineToolTaskEntity.getOrderSnapshotCraftSeq());
//                                    machineToolDataLog.setCraftName(machineToolTaskEntity.getCraftName());
//                                    machineToolDataLog.setStartTime(machineToolTaskEntity.getStartTime());
//                                    machineToolDataLog.setEndTime(machineToolTaskEntity.getEndTime());
//                                }
//                            } else {
//                                String catchUniqueId = toolLength + toolLength + toolNo;
//                                toolLifeMap.put(catchUniqueId, toolUsageTimeSub);
//                            }
//                            machineToolDataLog.setRfid(toolNo + toolLength + toolRadius);
//                            machineToolDataLog.setPosition(position);
//                            machineToolDataLog.setToolLife(toolLifeDouble);
//                            machineToolDataLog.setWarehouseId(idSnEntry.getKey());
//                            machineToolDataLog.setWarehouseName(warehouseRespository.getNameByWarehouseId(idSnEntry.getKey()));
//                            machineToolDataLog.setLength(toolLength + "");
//                            machineToolDataLog.setUniqueId(uniqueId);
//                            machineToolDataLog.setToolNo(toolNo);
//                            machineToolDataLog.setToolRadius(toolRadius + "");
//                            machineToolDataLog.setToolUsageTime(toolUsageTimeSub);
//                            if (ObjectUtil.isNotNull(o)) {
//                                machineToolDataLog.setProgram(CommonUtil.getProgramString(o));
//                            }
//                            if (machineToolDataLog.getTime() != 0) {
//                                insertList.add(machineToolDataLog);
//                            }
//                        }
//                    });
//                }
//            } catch (Exception e) {
//                log.error("刀参数据采集错误: ->{}" + System.currentTimeMillis() + e.getMessage());
//            }
//        });
//        if (CollectionUtil.isNotEmpty(insertList)) {
//            machineToolDataLogMapper.insertBatchSomeColumn(insertList);
//        }
//        ;
//    }

//    @PostConstruct
//    public void recordMachineToolStatus() {
//        initMachineToolStatus();
//        //countMap.forEach();
//        //开启定时任务线程池
//        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
//        scheduledThreadPool.scheduleAtFixedRate(() -> {
//
//                },
//                5L,//延迟30秒执行
//                5L,//每隔60秒执行
//                TimeUnit.SECONDS);
//
//    }

    //@PostConstruct
    private void saveMachineToolStatusTask() {
        List<MachineToolStatus> machineToolStatusList = new ArrayList<>();
        snMap.forEach((key, value) -> {
            List<MachineToolStatus> insert1List = new ArrayList<>();
            List<ProgramDurationTimeEntity> insertDurationList = new ArrayList<>();
            String s = statusMap.get(value);
            try {
                DeviceClient deviceClient = toolScheduleService.ConnectDevice(value);
                String id = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/STATUS");
                List<Object> result = deviceClient.easyQuery(5000, new QueryRequestItem.Builder()
                        .id(id).build());
                Object statusObject = deviceClient.easyQuery(5000,
                        new QueryRequestItem.Builder().id(id).operation(Operation.GET_VALUE).build());

                //获取程序
                String programId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/PROGRAM");
                Object o = null;


                //获取进给速度
                String feedSpeedId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/FEED_SPEED");
                List<?> feedSpeed = deviceClient.easyQuery(5000,
                        new QueryRequestItem.Builder().id(feedSpeedId).operation(Operation.GET_VALUE).build());


                //获取程序
                String feedOverrideId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/FEED_OVERRIDE");
                List<?> feedOverride = deviceClient.easyQuery(5000,
                        new QueryRequestItem.Builder().id(feedOverrideId).operation(Operation.GET_VALUE).build());


                //获取主轴转速
                String spindleSeedId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/SPINDLE_SPEED");
                List<?> spindleSeed = deviceClient.easyQuery(5000,
                        new QueryRequestItem.Builder().id(feedOverrideId).operation(Operation.GET_VALUE).build());


                try {
                    o = deviceClient.easyQuery(5000,
                            new QueryRequestItem.Builder().id(programId).operation(Operation.GET_VALUE).build());
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
                if (!s.equals(CommonUtil.getProgramString(statusObject)) || ((ObjectUtil.isNotNull(CommonUtil.getProgramString(o))) && !programMap.get(value).equals(CommonUtil.getProgramString(o)))) {
                    QueryWrapper<MachineToolStatus> wrapper = new QueryWrapper<>();
                    wrapper.orderByDesc("create_time");
                    wrapper.eq("sn_code", value);
                    wrapper.last("LIMIT 1");
                    MachineToolStatus existStatus = machineToolStatusMapper.selectOne(wrapper);
                    MachineToolStatus machineToolStatus = new MachineToolStatus();
                    if (ObjectUtil.isNotNull(existStatus)) {
                        machineToolStatus.setTime(new Date().getTime() - existStatus.getCreateTime().getTime());
                    }
                    String program = ObjectUtil.isNotNull(CommonUtil.getProgramString(o)) ? CommonUtil.getProgramString(o) : "";
                    //校验是否为海德汉机床
                    String feedSpeedStr = "";
                    if (!groupMachineToolMap.getOrDefault(value, false)) {
                        feedSpeedStr = ObjectUtil.isNotNull(CommonUtil.getProgramString(feedSpeed)) ? CommonUtil.getProgramString(feedSpeed) : "";
                    }
                    String spindleSeedStr = "";
                    if (!groupMachineToolMap.getOrDefault(value, false)) {
                        spindleSeedStr = ObjectUtil.isNotNull(CommonUtil.getProgramString(spindleSeed)) ? CommonUtil.getProgramString(spindleSeed) : "";
                    }
                    String feedOverrideStr = ObjectUtil.isNotNull(CommonUtil.getProgramString(feedOverride)) ? CommonUtil.getProgramString(feedOverride) : "";
                    machineToolStatus.setStatus(CommonUtil.getProgramString(statusObject));
                    machineToolStatus.setProgram(program);
                    machineToolStatus.setSnCode(value);
                    machineToolStatus.setCreateTime(new Date());
                    insert1List.add(machineToolStatus);
//                    if(CommonUtil.getProgramString(statusObject) .equals("running")){
//                        buildInsertDurationList(insertDurationList ,program , value , machineToolStatus.getTime() , feedSpeedStr , feedOverrideStr);
//                    }
                    if (s.equals("running")) {
                        buildInsertDurationList(insertDurationList, programMap.get(value), value, machineToolStatus.getTime(), feedSpeedStr, feedOverrideStr, spindleSeedStr);
                    }
                    programMap.put(value, CommonUtil.getProgramString(o));
                    statusMap.put(value, CommonUtil.getProgramString(statusObject));
                }
            } catch (Exception e) {
                if (retryCount > 3) {
                    if (!s.equals("offline")) {
                        MachineToolStatus machineToolStatus = new MachineToolStatus();
                        machineToolStatus.setStatus("offline");
                        machineToolStatus.setProgram("");
                        machineToolStatus.setSnCode(value);
                        machineToolStatus.setCreateTime(new Date());
                        insert1List.add(machineToolStatus);
                        statusMap.put(value, "offline");
                        retryCount = 0;
                    }
                    log.error("刀参数据采集错误: ->{}" + System.currentTimeMillis() + e.getMessage());
                } else {
                    retryCount += 1;
                }
            }
            if (CollectionUtil.isNotEmpty(insert1List)) {
                machineToolStatusMapper.insertBatchSomeColumn(insert1List);
            }
            if (CollectionUtil.isNotEmpty(insertDurationList)) {
                programDurationTimeMapper.insertBatchSomeColumn(insertDurationList);
            }
        });
        if (CollectionUtil.isNotEmpty(machineToolStatusList)) {
            machineToolStatusMapper.insertBatchSomeColumn(machineToolStatusList);
        }
    }

    public void buildInsertDurationList(List<ProgramDurationTimeEntity> insertDurationList, String program, String snCode, Long time, String feedSpeedStr, String feedOverride, String spindleSeed) {
        ProgramDurationTimeEntity programDurationTimeEntity = new ProgramDurationTimeEntity();
        programDurationTimeEntity.setTime(ObjectUtil.isNotNull(time) ? time : 0);
        programDurationTimeEntity.setCreateTime(new Date());
//        if(ObjectUtil.isNotNull(feedOverride)){
//            programDurationTimeEntity.setFeedOverride(feedOverride.equals("")? 0 : Integer.valueOf(feedOverride));
//        }
//        if(ObjectUtil.isNotNull(feedSpeedStr)){
//            programDurationTimeEntity.setFeedSpeed(feedSpeedStr.equals("")? 0 : Integer.valueOf(feedSpeedStr));
//        }
//        if(ObjectUtil.isNotNull(spindleSeed)){
//            programDurationTimeEntity.setSpindleSpeed(spindleSeed.equals("")? 0 : Integer.valueOf(spindleSeed));
//        }
        programDurationTimeEntity.setMachineToolName(warehouseRespository.getNameBySnCode(snCode));
        //处理program名
        String[] split = program.split("\\/");
        String[] split1 = program.split("\\\\");
        String subProgramName = "";
        if (split.length > split1.length) {
            subProgramName = split[split.length - 1];
        } else {
            subProgramName = split1[split1.length - 1];
        }
        programDurationTimeEntity.setProgram(subProgramName);
        insertDurationList.add(programDurationTimeEntity);
    }


    public void buildInsertDurationListReload(List<ProgramDurationTimeEntity> insertDurationList, String program, String snCode, Long time, String feedSpeedStr, String feedOverride, String spindleSeed) {
        ProgramDurationTimeEntity programDurationTimeEntity = new ProgramDurationTimeEntity();
        programDurationTimeEntity.setTime(ObjectUtil.isNotNull(time) ? time : 0);
        programDurationTimeEntity.setCreateTime(new Date());
        if (ObjectUtil.isNotNull(feedOverride)) {
            programDurationTimeEntity.setFeedOverride(feedOverride);
        }
        if (ObjectUtil.isNotNull(feedSpeedStr)) {
            programDurationTimeEntity.setFeedSpeed(feedSpeedStr);
        }
        if (ObjectUtil.isNotNull(spindleSeed)) {
            programDurationTimeEntity.setSpindleSpeed(spindleSeed);
        }
        programDurationTimeEntity.setMachineToolName(warehouseRespository.getNameBySnCode(snCode));
        //处理program名
        String[] split = program.split("\\/");
        String[] split1 = program.split("\\\\");
        String subProgramName = "";
        if (split.length > split1.length) {
            subProgramName = split[split.length - 1];
        } else {
            subProgramName = split1[split1.length - 1];
        }
        programDurationTimeEntity.setProgram(subProgramName);
        programDurationTimeMapper.insert(programDurationTimeEntity);
    }

    @NotNull
    private void initMachineToolStatus() {
        List<MachineToolStatus> insertList = new ArrayList<>();
        snMap.forEach((key, value) -> {
            try {
                DeviceClient deviceClient = toolScheduleService.ConnectDevice(value);
                String id = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/STATUS");
                List<Object> result = deviceClient.easyQuery(2000, new QueryRequestItem.Builder()
                        .id(id).build());
                Object statusObject = deviceClient.easyQuery(3000,
                        new QueryRequestItem.Builder().id(id).operation(Operation.GET_VALUE).build());
                statusMap.put(value, CommonUtil.getProgramString(statusObject));

                //获取程序
                String programId = deviceClient.getIdOf("/NC_LINK_ROOT/MACHINE/CONTROLLER/PROGRAM");
                Object o = null;
                try {
                    o = deviceClient.easyQuery(3000,
                            new QueryRequestItem.Builder().id(programId).operation(Operation.GET_VALUE).build());
                } catch (Exception e) {
                    log.error(e.getMessage());
                }

                MachineToolStatus machineToolStatus = new MachineToolStatus();
                machineToolStatus.setStatus(CommonUtil.getProgramString(statusObject));
                machineToolStatus.setProgram(ObjectUtil.isNotNull(CommonUtil.getProgramString(o)) ? CommonUtil.getProgramString(o) : "");
                //存入程序内存map
                programMap.put(value, ObjectUtil.isNotNull(CommonUtil.getProgramString(o)) ? CommonUtil.getProgramString(o) : "");
                machineToolStatus.setSnCode(value);
                machineToolStatus.setCreateTime(new Date());
                insertList.add(machineToolStatus);

            } catch (Exception e) {
                MachineToolStatus machineToolStatus = new MachineToolStatus();
                machineToolStatus.setStatus("offline");
                machineToolStatus.setProgram("");
                machineToolStatus.setSnCode(value);
                machineToolStatus.setCreateTime(new Date());
                insertList.add(machineToolStatus);
                statusMap.put(value, "offline");
            }
        });
        if (CollectionUtil.isNotEmpty(insertList)) {
            machineToolStatusMapper.insertBatchSomeColumn(insertList);
        }
    }


}
